home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / abuse / src / innet.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-11  |  17.2 KB  |  710 lines

  1. /*
  2.  
  3.   This file is a combination of :
  4.     src/net/unix/unixnfc.c 
  5.     src/net/unix/netdrv.c 
  6.     src/net/unix/undrv.c
  7.  
  8.     netdrv & undrv compile to a stand-alone program with talk with unixnfc
  9. via a FIFO in /tmp, using a RPC-like scheme.  This versions runs inside
  10. of a abuse and therefore is a bit simpler.
  11.  
  12.  
  13. */
  14. #include "demo.hpp"
  15. #include "macs.hpp"
  16. #include "specs.hpp"
  17. #include "level.hpp"
  18. #include "game.hpp"
  19. #include <stdio.h>
  20. #include "timing.hpp"
  21. #include "fileman.hpp"
  22. #include "netface.hpp"
  23.  
  24. #include "gserver.hpp"
  25. #include "gclient.hpp"
  26. #include "dprint.hpp"
  27. #include "netcfg.hpp"
  28.  
  29.  
  30. extern char *symbol_str(char *name);
  31.  
  32. #ifdef __WATCOMC__
  33. #define getlogin() "DOS user"
  34. #endif
  35.  
  36.  
  37. base_memory_struct *base;   // points to shm_addr
  38. base_memory_struct local_base;
  39. net_address *net_server=NULL;
  40. extern int registered;
  41. net_protocol *prot=NULL;
  42. net_socket *comm_sock=NULL,*game_sock=NULL;
  43. extern char lsf[256];
  44. game_handler *game_face=NULL;
  45. int local_client_number=0;        // 0 is the server
  46. join_struct *join_array=NULL;      // points to an array of possible joining clients
  47. extern char *get_login();
  48. extern void set_login(char *name);
  49.  
  50. int net_init(int argc, char **argv)
  51. {
  52.   int i,x,db_level=0;
  53.   base=&local_base;
  54.  
  55.   local_client_number=0;
  56.  
  57.   if (!main_net_cfg)
  58.     main_net_cfg=new net_configuration;
  59.  
  60.  
  61.   if (!registered) return 0;
  62.  
  63.   for (i=1;i<argc;i++) 
  64.     if (!strcmp(argv[i],"-nonet"))
  65.       return 0;
  66.     else if (!strcmp(argv[i],"-port"))
  67.     {
  68.       if (i==argc-1 || !sscanf(argv[i+1],"%d",&x) || x<1 || x>0x7fff)
  69.       {
  70.         fprintf(stderr,"bad value following -port, use 1..32000\n");
  71.     return 0;
  72.       } else 
  73.     main_net_cfg->port=x;
  74.     } else if (!strcmp(argv[i],"-net") && i<argc-1)
  75.     {
  76.       i++;
  77.       strcpy(main_net_cfg->server_name,argv[i]);
  78.       main_net_cfg->state=net_configuration::CLIENT;
  79.     }
  80.     else if (!strcmp(argv[i],"-ndb"))
  81.     {
  82.       if (i==argc-1 || !sscanf(argv[i+1],"%d",&x) || x<1 || x>3)
  83.       {
  84.         fprintf(stderr,"bad value following -ndb, use 1..3\n");
  85.     return 0;
  86.       } else { db_level=x; }
  87.     } else if (!strcmp(argv[i],"-server"))
  88.        main_net_cfg->state=net_configuration::SERVER; 
  89.      else if (!strcmp(argv[i],"-min_players"))
  90.      {
  91.        i++; 
  92.        int x=atoi(argv[i]);
  93.        if (x>=1 && x<=8)
  94.          main_net_cfg->min_players=x;
  95.        else fprintf(stderr,"bad value for min_players use 1..8\n");
  96.      }
  97.  
  98.   
  99.   net_protocol *n=net_protocol::first,*usable=NULL;     // find a usable protocol from installed list
  100.   int total_usable=0;
  101.   for (;n;n=n->next)                                    // show a list of usables, just to be cute
  102.   {
  103.     fprintf(stderr,"Protocol %s : ",n->installed() ? "Installed" : "Not_installed");
  104.     fprintf(stderr,"%s\n",n->name());
  105.     if (n->installed()) 
  106.     {
  107.       total_usable++;
  108.       usable=n;
  109.     }      
  110.   }
  111.  
  112.   if (!usable) { fprintf(stderr,"No network protocols installed\n");  return 0; }
  113.   prot=usable;
  114.   prot->set_debug_printing((net_protocol::debug_type)db_level);
  115.   if (main_net_cfg->state==net_configuration::SERVER)
  116.     set_login(main_net_cfg->name);
  117.  
  118.   comm_sock=game_sock=NULL;
  119.   if (main_net_cfg->state==net_configuration::CLIENT)
  120.   {
  121.     dprintf("Attempting to locate server %s, please wait\n",main_net_cfg->server_name);
  122.     char *sn=main_net_cfg->server_name;
  123.     net_server=prot->get_node_address(sn,DEFAULT_COMM_PORT,0);
  124.     if (!net_server) { dprintf(symbol_str("unable_locate"));  exit(0); }   
  125.     dprintf("Server located!  Please wait while data loads....\n");
  126.   }
  127.  
  128.   fman=new file_manager(argc,argv,prot);                                       // manages remote file access
  129.   game_face=new game_handler;
  130.   join_array=(join_struct *)jmalloc(sizeof(join_struct)*MAX_JOINERS,"join array");
  131.   base->join_list=NULL;
  132.   base->mem_lock=0;
  133.   base->calc_crcs=0;
  134.   base->get_lsf=0;
  135.   base->wait_reload=0;
  136.   base->need_reload=0;
  137.   base->input_state=INPUT_COLLECTING;
  138.   base->current_tick=0;
  139.   base->packet.packet_reset();
  140.  
  141.   return 1;
  142. }
  143.  
  144.  
  145.  
  146.  
  147. int net_start()  // is the game starting up off the net? (i.e. -net hostname)
  148. {   return (main_net_cfg && main_net_cfg->state==net_configuration::CLIENT);  }
  149.  
  150.  
  151.  
  152. int kill_net()
  153.   if (game_face) delete game_face;  game_face=NULL;
  154.   if (join_array) jfree(join_array);  join_array=NULL;
  155.   if (game_sock) { delete game_sock; game_sock=NULL; }
  156.   if (comm_sock) { delete comm_sock; comm_sock=NULL; }
  157.   delete fman;  fman=NULL;
  158.   if (net_server) { delete net_server; net_server=NULL; }
  159.   if (prot) 
  160.   { 
  161.   
  162.     prot->cleanup(); 
  163.     prot=NULL; 
  164.     return 1;
  165.   } else return 0;
  166. }
  167.  
  168. void net_uninit()
  169. {
  170.   kill_net();
  171. }
  172.  
  173.  
  174. int NF_set_file_server(net_address *addr)
  175. {
  176.   if (prot)
  177.   {
  178.     fman->set_default_fs(addr);
  179.     net_socket *sock=prot->connect_to_server(addr,net_socket::SOCKET_SECURE);
  180.  
  181.     if (!sock) { printf("set_file_server::connect failed\n"); return 0; }
  182.     uchar cmd=CLIENT_CRC_WAITER;
  183.     if ( (sock->write(&cmd,1)!=1 && printf("set_file_server::writefailed\n")) ||
  184.      (sock->read(&cmd,1)!=1  && printf("set_file_server::read failed\n")))        // wait for confirmation that crc's are written
  185.     { delete sock; return 0; }
  186.     delete sock;
  187.     return cmd; 
  188.   } else return 0;
  189. }
  190.  
  191. int NF_set_file_server(char *name)
  192. {
  193.   if (prot)
  194.   {
  195.     net_address *addr=prot->get_node_address(name,DEFAULT_COMM_PORT,0);
  196.     if (addr)
  197.     {
  198.       int ret=NF_set_file_server(addr);
  199.       delete addr;
  200.       return ret;
  201.     } else return 0;
  202.   } else return 0;
  203. }
  204.  
  205.  
  206. int NF_open_file(char *filename, char *mode)
  207. {
  208.   if (prot)
  209.     return fman->rf_open_file(filename,mode);
  210.   else return -2;
  211. }
  212.  
  213.  
  214. long NF_close(int fd)
  215. {
  216.   if (prot)
  217.     return fman->rf_close(fd);
  218.   else return 0;
  219. }
  220.  
  221. long NF_read(int fd, void *buf, long size)
  222. {
  223.   if (prot)
  224.     return fman->rf_read(fd,buf,size);
  225.   else return 0;
  226. }
  227.  
  228. long NF_filelength(int fd)
  229. {
  230.   if (prot)
  231.     return fman->rf_file_size(fd);
  232.   else return 0;
  233. }
  234.  
  235. long NF_seek(int fd, long offset)
  236. {
  237.   if (prot)
  238.     return fman->rf_seek(fd,offset);
  239.   else return 0;
  240. }
  241.  
  242. long NF_tell(int fd)
  243. {
  244.   if (prot)
  245.     return fman->rf_tell(fd);
  246.   else return 0;
  247. }
  248.  
  249.  
  250. void service_net_request() 
  251. {
  252.   if (prot)
  253.   {
  254.     if (prot->select(0))  // anything happening net-wise?
  255.     {
  256.       if (comm_sock && comm_sock->ready_to_read())  // new connection?
  257.       {
  258.                 net_address *addr;
  259.             
  260.                 net_socket *new_sock=comm_sock->accept(addr);    
  261.                 if (new_sock)
  262.                 {
  263.                   uchar client_type;
  264.                   if (new_sock->read(&client_type,1)!=1)
  265.                   {
  266.                     delete addr;    
  267.                     delete new_sock;
  268.                   }
  269.                   else
  270.                   {
  271.                     switch (client_type)
  272.                     {
  273.                       case CLIENT_NFS :
  274.                       {
  275.                                 delete addr;    
  276.                                 fman->add_nfs_client(new_sock);
  277.                       } break;
  278.                       case CLIENT_CRC_WAITER :
  279.                       {        
  280.                                 crc_man.write_crc_file(NET_CRC_FILENAME);       // return 0 on failure
  281.                                 client_type=1;                                  // confirmation byte
  282.                                 new_sock->write(&client_type,1);
  283.                                 delete new_sock;                                // done with this socket now
  284.                                 delete addr;    
  285.                       } break;
  286.                       case CLIENT_LSF_WAITER :          // wants to know which .lsp file to start with
  287.                       {
  288.                                 uchar len=strlen(lsf);
  289.                                 new_sock->write(&len,1);
  290.                                 new_sock->write(lsf,len);
  291.                                 delete new_sock;
  292.                                 delete addr;
  293.                       } break;
  294.                       default :
  295.                       {
  296.                                 if (game_face->add_client(client_type,new_sock,addr)==0)  // ask server or client to add new client
  297.                                 {
  298.                                   delete addr;
  299.                                   delete new_sock;
  300.                                 }
  301.                       } break;
  302.                     }
  303.                   }            
  304.                 }
  305.       }
  306.       if (!game_face->process_net())
  307.       {
  308.                 delete game_face;
  309.                 game_face=new game_handler;
  310.       }
  311.       fman->process_net();      
  312.     }
  313.   }
  314. }
  315.  
  316.  
  317. int get_remote_lsf(net_address *addr, char *filename)  // filename should be 256 bytes
  318. {
  319.   if (prot)
  320.   {
  321.     net_socket *sock=prot->connect_to_server(addr,net_socket::SOCKET_SECURE);
  322.     if (!sock) return 0;
  323.  
  324.     uchar ctype=CLIENT_LSF_WAITER;
  325.     uchar len;
  326.  
  327.     if (sock->write(&ctype,1)!=1 ||
  328.                 sock->read(&len,1)!=1 || len==0 ||
  329.                 sock->read(filename,len)!=len)
  330.     {
  331.       delete sock; 
  332.       return 0;
  333.     } 
  334.  
  335.     delete sock;
  336.     return 1;  
  337.  
  338.   } else return 0;
  339. }
  340.  
  341. void server_check() { ; } 
  342.  
  343. int request_server_entry()
  344. {
  345.   if (prot && main_net_cfg)
  346.   {
  347.     if (!net_server) return 0;
  348.  
  349.     if (game_sock) delete game_sock;
  350.     dprintf("Joining game in progress, hang on....\n");
  351.  
  352.     game_sock=prot->create_listen_socket(main_net_cfg->port+1,net_socket::SOCKET_FAST);     // this is used for fast game packet transmission
  353.     if (!game_sock) { if (comm_sock) delete comm_sock; comm_sock=NULL; prot=NULL; return 0; }
  354.     game_sock->read_selectable();
  355.  
  356.     net_socket *sock=prot->connect_to_server(net_server,net_socket::SOCKET_SECURE);
  357.     if (!sock)
  358.     { 
  359.       fprintf(stderr,"unable to connect to server\n");
  360.       return 0;
  361.     }
  362.  
  363.     uchar ctype=CLIENT_ABUSE;
  364.     ushort port=lstl(main_net_cfg->port+1),cnum;
  365.  
  366.     uchar reg;
  367.     if (sock->write(&ctype,1)!=1 ||   // send server out game port
  368.                 sock->read(®,1)!=1)        // is remote engine registered?
  369.     { delete sock; return 0; }
  370.  
  371.     if (reg==2)   // too many players
  372.     {
  373.       fprintf(stderr,symbol_str("max_players"));
  374.       delete sock;
  375.       return 0;
  376.     }
  377.  
  378.     // maker sure the two games are both registered or unregistered or sync problems
  379.     // will occur.
  380.  
  381.     if (reg && !registered)
  382.     {
  383.       fprintf(stderr,symbol_str("net_not_reg"));
  384.       delete sock; 
  385.       return 0;
  386.     } 
  387.  
  388.     if (!reg && registered)
  389.     {
  390.       fprintf(stderr,symbol_str("server_not_reg"));
  391.       delete sock;
  392.       return 0;
  393.     }
  394.  
  395.     char uname[256];
  396.     if (get_login())
  397.       strcpy(uname,get_login());
  398.     else strcpy(uname,"unknown");
  399.     uchar len=strlen(uname)+1;
  400.     short nkills;
  401.  
  402.     if (sock->write(&len,1)!=1 ||
  403.                 sock->write(uname,len)!=len || 
  404.                 sock->write(&port,2)!=2  ||            // send server out game port
  405.                 sock->read(&port,2)!=2   ||            // read server's game port
  406.                 sock->read(&nkills,2)!=2 ||
  407.                 sock->read(&cnum,2)!=2   || cnum==0    // read player number (cannot be 0 because 0 is server)
  408.                 )
  409.     { delete sock; return 0; }
  410.  
  411.     nkills=lstl(nkills);
  412.     port=lstl(port);
  413.     cnum=lstl(cnum);
  414.     
  415.     main_net_cfg->kills=nkills;
  416.     net_address *addr=net_server->copy();
  417.     addr->set_port(port);
  418.  
  419.     delete game_face;
  420.     game_face=new game_client(sock,addr);
  421.     delete addr;
  422.  
  423.     local_client_number=cnum;
  424.     return cnum;
  425.   } else return 0;
  426. }
  427.  
  428. int reload_start()
  429. {
  430.   if (prot)
  431.     return game_face->start_reload();
  432.   else return 0;
  433. }
  434.  
  435. int reload_end()
  436. {
  437.   if (prot)
  438.     return game_face->end_reload();
  439.   else return 0;
  440. }
  441.  
  442.  
  443. void net_reload()
  444. {
  445.   if (prot)
  446.   {
  447.     if (net_server)
  448.     {
  449.       if (current_level)
  450.         delete current_level;
  451.       bFILE *fp;
  452.  
  453.       if (!reload_start()) return ;
  454.  
  455.       do {            // make sure server saves the file
  456.                 fp=open_file(NET_STARTFILE,"rb");
  457.                 if (fp->open_failure()) { delete fp; fp=NULL; }
  458.       } while (!fp);
  459.  
  460.       spec_directory sd(fp);  
  461.  
  462.       spec_entry *e=sd.find("Copyright 1995 Crack dot Com, All Rights reserved"); 
  463.       if (!e)
  464.       { 
  465.                 the_game->show_help("This level is missing copyright information, cannot load\n");
  466.                 current_level=new level(100,100,"untitled");
  467.                 the_game->need_refresh();
  468.       }
  469.       else 
  470.         current_level=new level(&sd,fp,NET_STARTFILE);
  471.  
  472.       delete fp;     
  473.       base->current_tick=(current_level->tick_counter()&0xff); 
  474.  
  475.       reload_end();
  476.     } else if (current_level)
  477.     {
  478.       
  479.       join_struct *join_list=base->join_list;
  480.  
  481.  
  482.       while (join_list)
  483.       {
  484.     
  485.                 view *f=player_list;
  486.                 for (;f && f->next;f=f->next);      // find last player, add one for pn
  487.                 int i,st=0;
  488.                 for (i=0;i<total_objects;i++)
  489.                 if (!strcmp(object_names[i],"START"))
  490.                 st=i;
  491.             
  492.                 game_object *o=create(current_start_type,0,0);
  493.                 game_object *start=current_level->get_random_start(320,NULL);
  494.                 if (start) { o->x=start->x; o->y=start->y; }
  495.                 else { o->x=100; o->y=100; }
  496.             
  497.                 f->next=new view(o,NULL,join_list->client_id);
  498.                 strcpy(f->next->name,join_list->name);
  499.                 o->set_controller(f->next);
  500.             
  501.                 if (start)
  502.                 current_level->add_object_after(o,start);
  503.                 else
  504.                 current_level->add_object(o);
  505.             
  506.                 view *v=f->next;      
  507.             
  508.                 v->cx1=5;
  509.                 v->cy1=5;
  510.                 v->cx2=319-5;
  511.                 v->cy2=199-5;
  512.                 join_list=join_list->next;
  513.       }     
  514.       base->join_list=NULL;
  515.       current_level->save(NET_STARTFILE,1);
  516.       base->mem_lock=0;
  517.  
  518.  
  519.       jwindow *j=eh->new_window(0,yres/2,-1,-1,new info_field(WINDOW_FRAME_LEFT,
  520.                                    WINDOW_FRAME_TOP,
  521.                                    0,symbol_str("resync"),
  522.                           new button(WINDOW_FRAME_LEFT,
  523.                              WINDOW_FRAME_TOP+eh->font()->height()+5,ID_NET_DISCONNECT,
  524.                              symbol_str("slack"),NULL)),symbol_str("hold!"))
  525. ;
  526.  
  527.   
  528.  
  529.       eh->flush_screen();
  530.       if (!reload_start()) return ;
  531.  
  532.       base->input_state=INPUT_RELOAD;    // if someone missed the game tick with the RELOAD data in it, make sure the get it
  533.   
  534.       // wait for all client to reload the level with the new players
  535.       do  
  536.       { 
  537.                 service_net_request();
  538.                 if (eh->event_waiting())
  539.                 {
  540.                   event ev;
  541.                   do
  542.                   {
  543.                     eh->get_event(ev);
  544.                     if (ev.type==EV_MESSAGE && ev.message.id==ID_NET_DISCONNECT)
  545.                     {
  546.                       game_face->end_reload(1);
  547.                       base->input_state=INPUT_PROCESSING; 
  548.                     }
  549.             
  550.                   } while (eh->event_waiting()); 
  551.             
  552.                   eh->flush_screen();
  553.                 }
  554.  
  555.       } while (!reload_end());
  556.       eh->close_window(j);
  557.       unlink(NET_STARTFILE);
  558.  
  559.       the_game->reset_keymap();
  560.  
  561.       base->input_state=INPUT_COLLECTING;
  562.  
  563.     }     
  564.   }
  565. }
  566.  
  567.  
  568. int client_number() { return local_client_number; }
  569.  
  570.  
  571. void send_local_request()
  572. {
  573.  
  574.   if (prot)
  575.   {    
  576.     if (current_level)
  577.       base->current_tick=(current_level->tick_counter()&0xff); 
  578.     game_face->add_engine_input();
  579.   } else base->input_state=INPUT_PROCESSING;
  580.  
  581. }
  582.  
  583.  
  584. void kill_slackers()
  585. {
  586.   if (prot)
  587.   {
  588.     if (!game_face->kill_slackers())
  589.     {
  590.       delete game_face;
  591.       game_face=new game_handler();
  592.     }
  593.   }
  594. }
  595.  
  596. int get_inputs_from_server(unsigned char *buf)
  597. {
  598.   if (prot && base->input_state!=INPUT_PROCESSING)      // if input is not here, wait on it
  599.   {
  600.     time_marker start;
  601.  
  602.     int total_retry=0;
  603.     jwindow *abort=NULL;
  604.  
  605.     while (base->input_state!=INPUT_PROCESSING)
  606.     { 
  607.       if (!prot)
  608.       { 
  609.     base->input_state=INPUT_PROCESSING; 
  610.     return 1; 
  611.       }
  612.       service_net_request();
  613.  
  614.       time_marker now;                   // if this is taking to long, the packet was probably lost, ask for it to be resent
  615.  
  616.       if (now.diff_time(&start)>0.05)
  617.       {
  618.     if (prot->debug_level(net_protocol::DB_IMPORTANT_EVENT))
  619.       fprintf(stderr,"(missed packet)");
  620.  
  621.     
  622.     game_face->input_missing();
  623.     start.get_time();
  624.  
  625.     total_retry++;
  626.     if (total_retry==12000)    // 2 minutes and nothing
  627.     {
  628.       abort=eh->new_window(0,yres/2,-1,eh->font()->height()*4,
  629.                    new info_field(WINDOW_FRAME_LEFT,
  630.                           WINDOW_FRAME_TOP,
  631.                           0,symbol_str("waiting"),
  632.                           new button(WINDOW_FRAME_LEFT,
  633.                              WINDOW_FRAME_TOP+eh->font()->height()+5,ID_NET_DISCONNECT,
  634.                              symbol_str("slack"),NULL)),symbol_str("Error"));      
  635.       eh->flush_screen();
  636.     }
  637.       }
  638.       if (abort)
  639.       {
  640.     if (eh->event_waiting())
  641.     {
  642.       event ev;
  643.       do
  644.       {
  645.         eh->get_event(ev);
  646.         if (ev.type==EV_MESSAGE && ev.message.id==ID_NET_DISCONNECT)
  647.         {
  648.           kill_slackers();
  649.           base->input_state=INPUT_PROCESSING; 
  650.         }
  651.       } while (eh->event_waiting());
  652.  
  653.       eh->flush_screen();
  654.     }
  655.       }
  656.     }
  657.  
  658.     if (abort)
  659.     {
  660.       eh->close_window(abort);
  661.       the_game->reset_keymap();
  662.  
  663.     }
  664.   }
  665.  
  666.  
  667.   memcpy(base->last_packet.data,base->packet.data,base->packet.packet_size()+base->packet.packet_prefix_size());
  668.   
  669.   int size=base->packet.packet_size();  
  670.   memcpy(buf,base->packet.packet_data(),size);
  671.  
  672.   base->packet.packet_reset();
  673.   base->mem_lock=0;
  674.  
  675.   return size;
  676. }
  677.  
  678. int become_server(char *name)
  679. {
  680.   if (prot && main_net_cfg)
  681.   {
  682.     delete game_face;
  683.  
  684.     if (comm_sock) delete comm_sock;    
  685.     comm_sock=prot->create_listen_socket(main_net_cfg->port,net_socket::SOCKET_SECURE);   // this is used for incomming connections
  686.     if (!comm_sock) { prot=NULL; return 0; }
  687.     comm_sock->read_selectable();
  688.         prot->start_notify(0x9090, name, strlen(name));  // should we define a new socket for notifiers?
  689.  
  690.     if (game_sock) delete game_sock;
  691.     game_sock=prot->create_listen_socket(main_net_cfg->port+1,net_socket::SOCKET_FAST);     // this is used for fast game packet transmission
  692.     if (!game_sock) { if (comm_sock) delete comm_sock; comm_sock=NULL; prot=NULL; return 0; }
  693.     game_sock->read_selectable();
  694.  
  695.     game_face=new game_server;
  696.     local_client_number=0;
  697.     return 1;
  698.   }
  699.   return 0;
  700. }
  701.  
  702. void read_new_views() { ; }
  703.  
  704.  
  705. void wait_min_players()
  706. {
  707.   if (game_face) game_face->game_start_wait();
  708. }
  709.